home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 21 / AACD 21.iso / AACD / Utilities / Ghostscript / src / gdevpsft.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-01  |  26.4 KB  |  927 lines

  1. /* Copyright (C) 1999, 2000 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of AFPL Ghostscript.
  4.   
  5.   AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author or
  6.   distributor accepts any responsibility for the consequences of using it, or
  7.   for whether it serves any particular purpose or works at all, unless he or
  8.   she says so in writing.  Refer to the Aladdin Free Public License (the
  9.   "License") for full details.
  10.   
  11.   Every copy of AFPL Ghostscript must include a copy of the License, normally
  12.   in a plain ASCII text file named PUBLIC.  The License grants you the right
  13.   to copy, modify and redistribute AFPL Ghostscript, but only under certain
  14.   conditions described in the License.  Among other things, the License
  15.   requires that the copyright notice and this notice be preserved on all
  16.   copies.
  17. */
  18.  
  19. /*$Id: gdevpsft.c,v 1.4 2000/09/26 06:42:05 lpd Exp $ */
  20. /* Write an embedded TrueType font */
  21. #include "memory_.h"
  22. #include <stdlib.h>        /* for qsort */
  23. #include "gx.h"
  24. #include "gserrors.h"
  25. #include "gsmatrix.h"
  26. #include "gsutil.h"
  27. #include "gxfcid.h"
  28. #include "gxfont.h"
  29. #include "gxfont42.h"
  30. #include "gxttf.h"
  31. #include "stream.h"
  32. #include "spprint.h"
  33. #include "gdevpsf.h"
  34.  
  35. #define MAX_COMPOSITE_PIECES 3    /* adhoc */
  36.  
  37. /* ---------------- Utilities ---------------- */
  38.  
  39. #define ACCESS(base, length, vptr)\
  40.   BEGIN\
  41.     code = string_proc(pfont, (ulong)(base), length, &vptr);\
  42.     if (code < 0) return code;\
  43.   END
  44.  
  45. /* Pad to a multiple of 4 bytes. */
  46. private void
  47. put_pad(stream *s, uint length)
  48. {
  49.     static const byte pad_to_4[3] = {0, 0, 0};
  50.  
  51.     pwrite(s, pad_to_4, (uint)(-length & 3));
  52. }
  53.  
  54. /* Put short and long values on a stream. */
  55. private void
  56. put_ushort(stream *s, uint v)
  57. {
  58.     pputc(s, (byte)(v >> 8));
  59.     pputc(s, (byte)v);
  60. }
  61. private void
  62. put_ulong(stream *s, ulong v)
  63. {
  64.     put_ushort(s, (uint)(v >> 16));
  65.     put_ushort(s, (uint)v);
  66. }
  67. private void
  68. put_loca(stream *s, ulong offset, int indexToLocFormat)
  69. {
  70.     if (indexToLocFormat)
  71.     put_ulong(s, offset);
  72.     else
  73.     put_ushort(s, (uint)(offset >> 1));
  74. }
  75.  
  76. /* Get or put 2- or 4-byte quantities from/into a table. */
  77. #define U8(p) ((uint)((p)[0]))
  78. #define S8(p) (int)((U8(p) ^ 0x80) - 0x80)
  79. #define U16(p) (((uint)((p)[0]) << 8) + (p)[1])
  80. #define S16(p) (int)((U16(p) ^ 0x8000) - 0x8000)
  81. #define u32(p) get_u32_msb(p)
  82. private void
  83. put_u16(byte *p, uint v)
  84. {
  85.     p[0] = (byte)(v >> 8);
  86.     p[1] = (byte)v;
  87. }
  88. private void
  89. put_u32(byte *p, ulong v)
  90. {
  91.     p[0] = (byte)(v >> 24);
  92.     p[1] = (byte)(v >> 16);
  93.     p[2] = (byte)(v >> 8);
  94.     p[3] = (byte)v;
  95. }
  96. private ulong
  97. put_table(byte tab[16], const char *tname, ulong checksum, ulong offset,
  98.       uint length)
  99. {
  100.     memcpy(tab, (const byte *)tname, 4);
  101.     put_u32(tab + 4, checksum);
  102.     put_u32(tab + 8, offset + 0x40000000);
  103.     put_u32(tab + 12, (ulong)length);
  104.     return offset + round_up(length, 4);
  105. }
  106.  
  107. /* Write one range of a TrueType font. */
  108. private int
  109. write_range(stream *s, gs_font_type42 *pfont, ulong start, uint length)
  110. {
  111.     ulong base = start;
  112.     ulong limit = base + length;
  113.     int (*string_proc)(P4(gs_font_type42 *, ulong, uint, const byte **)) =
  114.     pfont->data.string_proc;
  115.  
  116.     if_debug3('l', "[l]write_range pos = %ld, start = %lu, length = %u\n",
  117.           stell(s), start, length);
  118.     while (base < limit) {
  119.     uint size = limit - base;
  120.     const byte *ptr;
  121.     int code;
  122.  
  123.     /* Write the largest block we can access consecutively. */
  124.     while ((code = string_proc(pfont, base, size, &ptr)) < 0) {
  125.         if (size <= 1)
  126.         return code;
  127.         size >>= 1;
  128.     }
  129.     pwrite(s, ptr, size);
  130.     base += size;
  131.     }
  132.     return 0;
  133. }
  134.  
  135. /*
  136.  * Determine the Macintosh glyph number for a given character, if any.
  137.  * If no glyph can be found, return -1 and store the name in *pstr.
  138.  */
  139. private int
  140. mac_glyph_index(gs_font *font, int ch, gs_const_string *pstr)
  141. {
  142.     gs_glyph glyph = font->procs.encode_char(font, (gs_char)ch,
  143.                          GLYPH_SPACE_NAME);
  144.  
  145.     if (glyph == gs_no_glyph)
  146.     return 0;        /* .notdef */
  147.     pstr->data = (const byte *)
  148.     font->procs.callbacks.glyph_name(glyph, &pstr->size);
  149.     if (glyph < gs_min_cid_glyph) {
  150.     gs_char mac_char;
  151.     gs_glyph mac_glyph;
  152.     gs_const_string mstr;
  153.  
  154.     /* Look (not very hard) for a match in the Mac glyph space. */
  155.     if (ch >= 32 && ch <= 126)
  156.         mac_char = ch - 29;
  157.     else if (ch >= 128 && ch <= 255)
  158.         mac_char = ch - 30;
  159.     else
  160.         return -1;
  161.     mac_glyph =
  162.         font->procs.callbacks.known_encode(mac_char,
  163.                            ENCODING_INDEX_MACGLYPH);
  164.     if (mac_glyph == gs_no_glyph)
  165.         return -1;
  166.     mstr.data =(const byte *)
  167.         font->procs.callbacks.glyph_name(mac_glyph, &mstr.size);
  168.     if (!bytes_compare(pstr->data, pstr->size, mstr.data, mstr.size))
  169.         return (int)mac_char;
  170.     }
  171.     return -1;
  172. }
  173.  
  174. /* ---------------- Individual tables ---------------- */
  175.  
  176. /* ------ cmap ------ */
  177.  
  178. /* Write a generated cmap table. */
  179. static const byte cmap_initial_0[] = {
  180.     0, 0,        /* table version # = 0 */
  181.     0, 2,        /* # of encoding tables = 2 */
  182.  
  183.     /* First table, Macintosh */
  184.     0, 1,        /* platform ID = Macintosh */
  185.     0, 0,        /* platform encoding ID = ??? */
  186.     0, 0, 0, 4+8+8,    /* offset to table start */
  187.     /* Second table, Windows */
  188.     0, 3,        /* platform ID = Microsoft */
  189.     0, 0,        /* platform encoding ID = unknown */
  190.     0, 0, 1, 4+8+8+6,    /* offset to table start */
  191.  
  192.     /* Start of Macintosh format 0 table */
  193.     0, 0,        /* format = 0, byte encoding table */
  194.     1, 6,        /* length */
  195.     0, 0        /* version number */
  196. };
  197. static const byte cmap_initial_6[] = {
  198.     0, 0,        /* table version # = 0 */
  199.     0, 2,        /* # of encoding tables = 2 */
  200.  
  201.     /* First table, Macintosh */
  202.     0, 1,        /* platform ID = Macintosh */
  203.     0, 0,        /* platform encoding ID = ??? */
  204.     0, 0, 0, 4+8+8,    /* offset to table start */
  205.     /* Second table, Windows */
  206.     0, 3,        /* platform ID = Microsoft */
  207.     0, 0,        /* platform encoding ID = unknown */
  208.     0, 0, 0, 4+8+8+10,    /* offset to table start */
  209.             /****** VARIABLE, add 2 x # of entries ******/
  210.  
  211.     /* Start of Macintosh format 6 table */
  212.     0, 6,        /* format = 6, trimmed table mapping */
  213.     0, 10,        /* length ****** VARIABLE, add 2 x # of entries ******/
  214.     0, 0,        /* version number */
  215.     0, 0,        /* first character code */
  216.     0, 0        /* # of entries ****** VARIABLE ****** */
  217. };
  218. static const byte cmap_initial_4[] = {
  219.     0, 0,        /* table version # = 0 */
  220.     0, 1,        /* # of encoding tables = 2 */
  221.  
  222.     /* Single table, Windows */
  223.     0, 3,        /* platform ID = Microsoft */
  224.     0, 0,        /* platform encoding ID = unknown */
  225.     0, 0, 0, 4+8    /* offset to table start */
  226. };
  227. static const byte cmap_sub_initial[] = {
  228.     0, 4,        /* format = 4, segment mapping */
  229.     0, 32,        /* length ** VARIABLE, add 2 x # of glyphs ** */
  230.     0, 0,        /* version # */
  231.     0, 4,        /* 2 x segCount */
  232.     0, 4,        /* searchRange = 2 x 2 ^ floor(log2(segCount)) */
  233.     0, 1,        /* floor(log2(segCount)) */
  234.     0, 0,        /* 2 x segCount - searchRange */
  235.  
  236.     0, 0,        /* endCount[0] **VARIABLE** */
  237.     255, 255,        /* endCount[1] */
  238.     0, 0,        /* reservedPad */
  239.     0, 0,        /* startCount[0] **VARIABLE** */
  240.     255, 255,        /* startCount[1] */
  241.     0, 0,        /* idDelta[0] */
  242.     0, 1,        /* idDelta[1] */
  243.     0, 4,        /* idRangeOffset[0] */
  244.     0, 0        /* idRangeOffset[1] */
  245. };
  246. private void
  247. write_cmap(stream *s, gs_font *font, uint first_code, int num_glyphs,
  248.        gs_glyph max_glyph, int options, uint cmap_length)
  249. {
  250.     byte cmap_sub[sizeof(cmap_sub_initial)];
  251.     byte entries[256 * 2];
  252.     int first_entry = 0, end_entry = num_glyphs;
  253.     bool can_use_trimmed = !(options & WRITE_TRUETYPE_NO_TRIMMED_TABLE);
  254.     uint merge = 0;
  255.     uint num_entries;
  256.     int i;
  257.  
  258.     /* Collect the table entries. */
  259.  
  260.     for (i = 0; i < num_glyphs; ++i) {
  261.     gs_glyph glyph =
  262.         font->procs.encode_char(font, (gs_char)i, GLYPH_SPACE_INDEX);
  263.     uint glyph_index;
  264.  
  265.     if (glyph == gs_no_glyph || glyph < gs_min_cid_glyph ||
  266.         glyph > max_glyph
  267.         )
  268.         glyph = gs_min_cid_glyph;
  269.     glyph_index = (uint)(glyph - gs_min_cid_glyph);
  270.     merge |= glyph_index;
  271.     put_u16(entries + 2 * i, glyph_index);
  272.     }
  273.     while (end_entry > first_entry && !U16(entries + 2 * end_entry - 2))
  274.     --end_entry;
  275.     while (first_entry < end_entry && !U16(entries + 2 * first_entry))
  276.     ++first_entry;
  277.     num_entries = end_entry - first_entry;
  278.  
  279.     /* Write the table header and Macintosh sub-table (if any). */
  280.     if (merge == (byte)merge && (num_entries <= 127 || !can_use_trimmed)) {
  281.     /* Use byte encoding format. */
  282.     memset(entries + 2 * num_glyphs, 0,
  283.            sizeof(entries) - 2 * num_glyphs);
  284.     pwrite(s, cmap_initial_0, sizeof(cmap_initial_0));
  285.     for (i = 0; i <= 0xff; ++i)
  286.         sputc(s, (byte)entries[2 * i + 1]);
  287.     } else if (can_use_trimmed) {
  288.     /* Use trimmed table format. */
  289.     byte cmap_data[sizeof(cmap_initial_6)];
  290.  
  291.     memcpy(cmap_data, cmap_initial_6, sizeof(cmap_initial_6));
  292.     put_u16(cmap_data + 18,
  293.         U16(cmap_data + 18) + num_entries * 2);  /* offset */
  294.     put_u16(cmap_data + 22,
  295.         U16(cmap_data + 22) + num_entries * 2);  /* length */
  296.     put_u16(cmap_data + 26, first_code + first_entry);
  297.     put_u16(cmap_data + 28, num_entries);
  298.     pwrite(s, cmap_data, sizeof(cmap_data));
  299.     pwrite(s, entries + first_entry * 2, num_entries * 2);
  300.     } else {
  301.     /*
  302.      * Punt.  Acrobat Reader 3 can't handle any other Mac table format.
  303.      * (AR3 for Linux doesn't seem to be able to handle Windows format,
  304.      * either, but maybe AR3 for Windows can.)
  305.      */
  306.     pwrite(s, cmap_initial_4, sizeof(cmap_initial_4));
  307.     }
  308.  
  309.     /* Write the Windows sub-table. */
  310.  
  311.     memcpy(cmap_sub, cmap_sub_initial, sizeof(cmap_sub_initial));
  312.     put_u16(cmap_sub + 2, U16(cmap_sub + 2) + num_entries * 2); /* length */
  313.     put_u16(cmap_sub + 14, first_code + end_entry - 1); /* endCount[0] */
  314.     put_u16(cmap_sub + 20, first_code + first_entry); /* startCount[0] */
  315.     pwrite(s, cmap_sub, sizeof(cmap_sub));
  316.     pwrite(s, entries + first_entry * 2, num_entries * 2);
  317.     put_pad(s, cmap_length);
  318. }
  319. private uint
  320. size_cmap(gs_font *font, uint first_code, int num_glyphs, gs_glyph max_glyph,
  321.       int options)
  322. {
  323.     stream poss;
  324.  
  325.     swrite_position_only(&poss);
  326.     write_cmap(&poss, font, first_code, num_glyphs, max_glyph, options, 0);
  327.     return stell(&poss);
  328. }
  329.  
  330. /* ------ name ------ */
  331.  
  332. /* Write a generated name table. */
  333. static const byte name_initial[] = {
  334.     0, 0,            /* format */
  335.     0, 1,            /* # of records = 1 */
  336.     0, 18,            /* start of string storage */
  337.  
  338.     0, 2,            /* platform ID = ISO */
  339.     0, 2,            /* encoding ID = ISO 8859-1 */
  340.     0, 0,            /* language ID (none) */
  341.     0, 6,            /* name ID = PostScript name */
  342.     0, 0,            /* length ****** VARIABLE ****** */
  343.     0, 0            /* start of string within string storage */
  344. };
  345. private uint
  346. size_name(const gs_const_string *font_name)
  347. {
  348.     return sizeof(name_initial) + font_name->size;
  349. }
  350. private void
  351. write_name(stream *s, const gs_const_string *font_name)
  352. {
  353.     byte name_bytes[sizeof(name_initial)];
  354.  
  355.     memcpy(name_bytes, name_initial, sizeof(name_initial));
  356.     put_u16(name_bytes + 14, font_name->size);
  357.     pwrite(s, name_bytes, sizeof(name_bytes));
  358.     pwrite(s, font_name->data, font_name->size);
  359.     put_pad(s, size_name(font_name));
  360. }
  361.  
  362. /* ------ OS/2 ------ */
  363.  
  364. /* Write a generated OS/2 table. */
  365. #define OS_2_LENGTH sizeof(ttf_OS_2_t)
  366. private void
  367. update_OS_2(ttf_OS_2_t *pos2, uint first_glyph, int num_glyphs)
  368. {
  369.     put_u16(pos2->usFirstCharIndex, first_glyph);
  370.     put_u16(pos2->usLastCharIndex, first_glyph + num_glyphs - 1);
  371. }
  372. private void
  373. write_OS_2(stream *s, gs_font *font, uint first_glyph, int num_glyphs)
  374. {
  375.     ttf_OS_2_t os2;
  376.  
  377.     /*
  378.      * We don't bother to set most of the fields.  The really important
  379.      * ones, which affect character mapping, are usFirst/LastCharIndex.
  380.      * We also need to set usWeightClass and usWidthClass to avoid
  381.      * crashing ttfdump.
  382.      */
  383.     memset(&os2, 0, sizeof(os2));
  384.     put_u16(os2.version, 1);
  385.     put_u16(os2.usWeightClass, 400); /* Normal */
  386.     put_u16(os2.usWidthClass, 5); /* Normal */
  387.     update_OS_2(&os2, first_glyph, num_glyphs);
  388.     if (first_glyph >= 0xf000)
  389.     os2.ulCodePageRanges[3] = 1; /* bit 31, symbolic */
  390.     pwrite(s, &os2, sizeof(os2));
  391.     put_pad(s, sizeof(os2));
  392. }
  393.  
  394. /* ------ post ------ */
  395.  
  396. /* Construct and then write the post table. */
  397. typedef struct post_glyph_s {
  398.     byte char_index;
  399.     byte size;
  400.     ushort glyph_index;
  401. } post_glyph_t;
  402. private int
  403. compare_post_glyphs(const void *pg1, const void *pg2)
  404. {
  405.     gs_glyph g1 = ((const post_glyph_t *)pg1)->glyph_index,
  406.     g2 = ((const post_glyph_t *)pg2)->glyph_index;
  407.  
  408.     return (g1 < g2 ? -1 : g1 > g2 ? 1 : 0);
  409. }
  410. typedef struct post_s {
  411.     post_glyph_t glyphs[256 + 1];
  412.     int count, glyph_count;
  413.     uint length;
  414. } post_t;
  415.  
  416. /*
  417.  * If necessary, compute the length of the post table.  Note that we
  418.  * only generate post entries for characters in the Encoding.
  419.  */
  420. private void
  421. compute_post(gs_font *font, post_t *post)
  422. {
  423.     int i;
  424.  
  425.     for (i = 0, post->length = 32 + 2; i <= 255; ++i) {
  426.     gs_const_string str;
  427.     gs_glyph glyph = font->procs.encode_char(font, (gs_char)i,
  428.                          GLYPH_SPACE_INDEX);
  429.     int mac_index = mac_glyph_index(font, i, &str);
  430.  
  431.     if (mac_index != 0) {
  432.         post->glyphs[post->count].char_index = i;
  433.         post->glyphs[post->count].size =
  434.         (mac_index < 0 ? str.size + 1 : 0);
  435.         post->glyphs[post->count].glyph_index = glyph - gs_min_cid_glyph;
  436.         post->count++;
  437.     }
  438.     }
  439.     if (post->count) {
  440.     int j;
  441.  
  442.     qsort(post->glyphs, post->count, sizeof(post->glyphs[0]),
  443.           compare_post_glyphs);
  444.     /* Eliminate duplicate references to the same glyph. */
  445.     for (i = j = 0; i < post->count; ++i) {
  446.         if (i == 0 ||
  447.         post->glyphs[i].glyph_index !=
  448.         post->glyphs[i - 1].glyph_index
  449.         ) {
  450.         post->length += post->glyphs[i].size;
  451.         post->glyphs[j++] = post->glyphs[i];
  452.         }
  453.     }
  454.     post->count = j;
  455.     post->glyph_count = post->glyphs[post->count - 1].glyph_index + 1;
  456.     }
  457.     post->length += post->glyph_count * 2;
  458. }
  459.  
  460. /* Write the post table */
  461. private void
  462. write_post(stream *s, gs_font *font, post_t *post)
  463. {
  464.     byte post_initial[32 + 2];
  465.     uint name_index;
  466.     uint glyph_index;
  467.     int i;
  468.  
  469.     memset(post_initial, 0, 32);
  470.     put_u32(post_initial, 0x00020000);
  471.     put_u16(post_initial + 32, post->glyph_count);
  472.     pwrite(s, post_initial, sizeof(post_initial));
  473.  
  474.     /* Write the name index table. */
  475.  
  476.     for (i = 0, name_index = 258, glyph_index = 0; i < post->count; ++i) {
  477.     gs_const_string str;
  478.     int ch = post->glyphs[i].char_index;
  479.     int mac_index = mac_glyph_index(font, ch, &str);
  480.  
  481.     for (; glyph_index < post->glyphs[i].glyph_index; ++glyph_index)
  482.         put_ushort(s, 0);
  483.     glyph_index++;
  484.     if (mac_index >= 0)
  485.         put_ushort(s, mac_index);
  486.     else {
  487.         put_ushort(s, name_index);
  488.         name_index++;
  489.     }
  490.     }
  491.  
  492.     /* Write the string names of the glyphs. */
  493.  
  494.     for (i = 0; i < post->count; ++i) {
  495.     gs_const_string str;
  496.     int ch = post->glyphs[i].char_index;
  497.     int mac_index = mac_glyph_index(font, ch, &str);
  498.  
  499.     if (mac_index < 0) {
  500.         spputc(s, str.size);
  501.         pwrite(s, str.data, str.size);
  502.     }
  503.     }
  504.     put_pad(s, post->length);
  505. }
  506.  
  507. /* ---------------- Main program ---------------- */
  508.  
  509. /* Write the definition of a TrueType font. */
  510. private int
  511. compare_table_tags(const void *pt1, const void *pt2)
  512. {
  513.     ulong t1 = u32(pt1), t2 = u32(pt2);
  514.  
  515.     return (t1 < t2 ? -1 : t1 > t2 ? 1 : 0);
  516. }
  517. private int
  518. psf_write_truetype_data(stream *s, gs_font_type42 *pfont, int options,
  519.             psf_glyph_enum_t *penum, bool is_subset,
  520.             const gs_const_string *alt_font_name)
  521. {
  522.     gs_font *const font = (gs_font *)pfont;
  523.     gs_const_string font_name;
  524.     int (*string_proc)(P4(gs_font_type42 *, ulong, uint, const byte **)) =
  525.     pfont->data.string_proc;
  526.     const byte *OffsetTable;
  527.     uint numTables_stored, numTables, numTables_out;
  528. #define MAX_NUM_TABLES 40
  529.     byte tables[MAX_NUM_TABLES * 16];
  530.     uint i;
  531.     ulong offset;
  532.     gs_glyph glyph, glyph_prev;
  533.     ulong max_glyph;
  534.     uint glyf_length, glyf_checksum = 0 /****** BOGUS ******/;
  535.     uint loca_length, loca_checksum[2];
  536.     uint numGlyphs;        /* original value from maxp */
  537.     byte head[56];        /* 0 mod 4 */
  538.     post_t post;
  539.     ulong head_checksum, file_checksum = 0;
  540.     int indexToLocFormat;
  541.     bool have_cmap = false,
  542.     have_name = !(options & WRITE_TRUETYPE_NAME),
  543.     have_OS_2 = false,
  544.     have_post = false;
  545.     uint cmap_length;
  546.     ulong OS_2_start;
  547.     uint OS_2_length = OS_2_LENGTH;
  548.     int code;
  549.  
  550.     if (alt_font_name)
  551.     font_name = *alt_font_name;
  552.     else
  553.     font_name.data = font->font_name.chars,
  554.         font_name.size = font->font_name.size;
  555.  
  556.     /*
  557.      * Count the number of tables, including the eventual glyf and loca
  558.      * (which may not actually be present in the font), and copy the
  559.      * table directory.
  560.      */
  561.  
  562.     ACCESS(0, 12, OffsetTable);
  563.     numTables_stored = U16(OffsetTable + 4);
  564.     for (i = numTables = 0; i < numTables_stored; ++i) {
  565.     const byte *tab;
  566.     const byte *data;
  567.     ulong start;
  568.     uint length;
  569.  
  570.     ACCESS(12 + i * 16, 16, tab);
  571.     start = u32(tab + 8);
  572.     length = u32(tab + 12);
  573.     if (!memcmp(tab, "head", 4)) {
  574.         if (length != 54)
  575.         return_error(gs_error_invalidfont);
  576.         ACCESS(start, length, data);
  577.         memcpy(head, data, length);
  578.     } else if (
  579.         !memcmp(tab, "gly", 3) /*glyf=synthesized, glyx=Adobe bogus*/ ||
  580.         !memcmp(tab, "loc", 3) /*loca=synthesized, locx=Adobe bogus*/ ||
  581.         !memcmp(tab, "gdir", 4) /*Adobe marker*/ ||
  582.         ((options & WRITE_TRUETYPE_CMAP) && !memcmp(tab, "cmap", 4))
  583.         )
  584.         DO_NOTHING;
  585.     else {
  586.         if (numTables == MAX_NUM_TABLES)
  587.         return_error(gs_error_limitcheck);
  588.         if (!memcmp(tab, "cmap", 4))
  589.         have_cmap = true;
  590.         else if (!memcmp(tab, "maxp", 4)) {
  591.         ACCESS(start, length, data);
  592.         numGlyphs = U16(data + 4);
  593.         } else if (!memcmp(tab, "name", 4))
  594.         have_name = true;
  595.         else if (!memcmp(tab, "OS/2", 4)) {
  596.         have_OS_2 = true;
  597.         if (length > OS_2_LENGTH)
  598.             return_error(gs_error_invalidfont);
  599.         OS_2_start = start;
  600.         OS_2_length = length;
  601.         continue;
  602.         } else if (!memcmp(tab, "post", 4))
  603.         have_post = true;
  604.         memcpy(&tables[numTables++ * 16], tab, 16);
  605.     }
  606.     }
  607.  
  608.     /*
  609.      * Enumerate the glyphs to get the size of glyf and loca,
  610.      * and to compute the checksums for these tables.
  611.      */
  612.  
  613.     /****** NO CHECKSUMS YET ******/
  614.     for (max_glyph = 0, glyf_length = 0;
  615.      (code = psf_enumerate_glyphs_next(penum, &glyph)) != 1;
  616.      ) {
  617.     uint glyph_index;
  618.     gs_const_string glyph_string;
  619.  
  620.     if (glyph < gs_min_cid_glyph)
  621.         return_error(gs_error_invalidfont);
  622.     glyph_index = glyph - gs_min_cid_glyph;
  623.     if_debug1('L', "[L]glyph_index %u\n", glyph_index);
  624.     if (pfont->data.get_outline(pfont, glyph_index, &glyph_string) >= 0) {
  625.         max_glyph = max(max_glyph, glyph_index);
  626.         glyf_length += glyph_string.size;
  627.         if_debug1('L', "[L]  size %u\n", glyph_string.size);
  628.     }
  629.     }
  630.     if_debug2('l', "[l]max_glyph = %lu, glyf_length = %lu\n",
  631.           (ulong)max_glyph, (ulong)glyf_length);
  632.     /*
  633.      * For subset fonts, we should trim the loca table so that it only
  634.      * contains entries through max_glyph.  Unfortunately, this would
  635.      * require changing numGlyphs in maxp, which in turn would affect hdmx,
  636.      * hhea, hmtx, vdmx, vhea, vmtx, and possibly other tables.  This is way
  637.      * more work than we want to do right now.
  638.      */
  639.     /*loca_length = (max_glyph + 2) << 2;*/
  640.     loca_length = (numGlyphs + 1) << 2;
  641.     indexToLocFormat = (glyf_length > 0x1fffc);
  642.     if (!indexToLocFormat)
  643.     loca_length >>= 1;
  644.  
  645.     /*
  646.      * If necessary, compute the length of the post table.  Note that we
  647.      * only generate post entries for characters in the Encoding.  */
  648.  
  649.     if (!have_post) {
  650.     memset(&post, 0, sizeof(post));
  651.     if (options & WRITE_TRUETYPE_POST)
  652.         compute_post(font, &post);
  653.     else
  654.         post.length = 32;    /* dummy table */
  655.     }
  656.  
  657.     /* Fix up the head table. */
  658.  
  659.     memset(head + 8, 0, 4);
  660.     head[51] = (byte)indexToLocFormat;
  661.     memset(head + 54, 0, 2);
  662.     for (head_checksum = 0, i = 0; i < 56; i += 4)
  663.     head_checksum += u32(&head[i]);
  664.  
  665.     /*
  666.      * Construct the table directory, except for glyf, loca, head, OS/2,
  667.      * and, if necessary, generated cmap, name, and post tables.
  668.      * Note that the existing directory is already sorted by tag.
  669.      */
  670.  
  671.     numTables_out = numTables + 4 +
  672.     !have_cmap + !have_name + !have_post;
  673.     offset = 12 + numTables_out * 16;
  674.     for (i = 0; i < numTables; ++i) {
  675.     byte *tab = &tables[i * 16];
  676.     ulong length = u32(tab + 12);
  677.  
  678.     offset += round_up(length, 4);
  679.     }
  680.  
  681.     /* Make the table directory entries for generated tables. */
  682.  
  683.     {
  684.     byte *tab = &tables[numTables * 16];
  685.  
  686.     offset = put_table(tab, "glyf", glyf_checksum, offset, glyf_length);
  687.     tab += 16;
  688.  
  689.     offset = put_table(tab, "loca", loca_checksum[indexToLocFormat],
  690.                offset, loca_length);
  691.     tab += 16;
  692.  
  693.     if (!have_cmap) {
  694.         cmap_length = size_cmap(font, 0xf000, 256,
  695.                     gs_min_cid_glyph + max_glyph, options);
  696.         offset = put_table(tab, "cmap", 0L /****** NO CHECKSUM ******/,
  697.                    offset, cmap_length);
  698.         tab += 16;
  699.     }
  700.  
  701.     if (!have_name) {
  702.         offset = put_table(tab, "name", 0L /****** NO CHECKSUM ******/,
  703.                    offset, size_name(&font_name));
  704.         tab += 16;
  705.     }
  706.  
  707.     offset = put_table(tab, "OS/2", 0L /****** NO CHECKSUM ******/,
  708.                offset, OS_2_length);
  709.     tab += 16;
  710.  
  711.     if (!have_post) {
  712.         offset = put_table(tab, "post", 0L /****** NO CHECKSUM ******/,
  713.                    offset, post.length);
  714.         tab += 16;
  715.     }
  716.  
  717.     /*
  718.      * Note that the 'head' table must have length 54, even though
  719.      * it occupies 56 bytes on the file.
  720.      */
  721.     offset = put_table(tab, "head", head_checksum, offset, 54);
  722.     tab += 16;
  723.     }
  724.     numTables = numTables_out;
  725.  
  726.     /* Write the font header. */
  727.  
  728.     {
  729.     static const byte version[4] = {0, 1, 0, 0};
  730.  
  731.     pwrite(s, version, 4);
  732.     }
  733.     put_ushort(s, numTables);
  734.     for (i = 0; 1 << i <= numTables; ++i)
  735.     DO_NOTHING;
  736.     --i;
  737.     put_ushort(s, 16 << i);    /* searchRange */
  738.     put_ushort(s, i);        /* entrySelectors */
  739.     put_ushort(s, numTables * 16 - (16 << i)); /* rangeShift */
  740.  
  741.     /* Write the table directory. */
  742.  
  743.     qsort(tables, numTables, 16, compare_table_tags);
  744.     offset = 12 + numTables * 16;
  745.     for (i = 0; i < numTables; ++i) {
  746.     const byte *tab = &tables[i * 16];
  747.     byte entry[16];
  748.  
  749.     memcpy(entry, tab, 16);
  750.     if (entry[8] < 0x40) {
  751.         /* Not a generated table. */
  752.         uint length = u32(tab + 12);
  753.  
  754.         put_u32(entry + 8, offset);
  755.         offset += round_up(length, 4);
  756.     } else {
  757.         entry[8] -= 0x40;
  758.     }
  759.     pwrite(s, entry, 16);
  760.     }
  761.  
  762.     /* Write tables other than the ones we generate here. */
  763.  
  764.     for (i = 0; i < numTables; ++i) {
  765.     const byte *tab = &tables[i * 16];
  766.  
  767.     if (tab[8] < 0x40) {
  768.         ulong start = u32(tab + 8);
  769.         uint length = u32(tab + 12);
  770.  
  771.         write_range(s, pfont, start, length);
  772.         put_pad(s, length);
  773.     }
  774.     }
  775.  
  776.     /* Write glyf. */
  777.  
  778.     if (is_subset)
  779.     psf_enumerate_glyphs_reset(penum);
  780.     else
  781.     psf_enumerate_glyphs_begin(penum, font, NULL, max_glyph + 1,
  782.                    GLYPH_SPACE_INDEX);
  783.     for (offset = 0; psf_enumerate_glyphs_next(penum, &glyph) != 1; ) {
  784.     gs_const_string glyph_string;
  785.  
  786.     if (pfont->data.get_outline(pfont, glyph - gs_min_cid_glyph,
  787.                     &glyph_string) >= 0) {
  788.         pwrite(s, glyph_string.data, glyph_string.size);
  789.         offset += glyph_string.size;
  790.         if_debug2('L', "[L]glyf index = %u, size = %u\n",
  791.               i, glyph_string.size);
  792.     }
  793.     }
  794.     if_debug1('l', "[l]glyf final offset = %lu\n", offset);
  795.     put_pad(s, (uint)offset);
  796.  
  797.     /* Write loca. */
  798.  
  799.     psf_enumerate_glyphs_reset(penum);
  800.     glyph_prev = gs_min_cid_glyph;
  801.     for (offset = 0; psf_enumerate_glyphs_next(penum, &glyph) != 1; ) {
  802.     gs_const_string glyph_string;
  803.  
  804.     for (; glyph_prev <= glyph; ++glyph_prev)
  805.         put_loca(s, offset, indexToLocFormat);
  806.     if (pfont->data.get_outline(pfont, glyph - gs_min_cid_glyph,
  807.                     &glyph_string) >= 0)
  808.         offset += glyph_string.size;
  809.     }
  810.     /* Pad to numGlyphs + 1 entries (including the trailing entry). */
  811.     for (; glyph_prev <= gs_min_cid_glyph + numGlyphs; ++glyph_prev)
  812.     put_loca(s, offset, indexToLocFormat);
  813.     put_pad(s, loca_length);
  814.  
  815.     /* If necessary, write cmap, name, and OS/2. */
  816.  
  817.     if (!have_cmap)
  818.     write_cmap(s, font, 0xf000, 256, gs_min_cid_glyph + max_glyph,
  819.            options, cmap_length);
  820.     if (!have_name)
  821.     write_name(s, &font_name);
  822.     if (!have_OS_2)
  823.     write_OS_2(s, font, 0xf000, 256);
  824.     else if (!have_cmap) {
  825.     /*
  826.      * Adjust the first and last character indices in the OS/2 table
  827.      * to reflect the values in the generated cmap.
  828.      */
  829.     const byte *pos2;
  830.     ttf_OS_2_t os2;
  831.  
  832.     ACCESS(OS_2_start, OS_2_length, pos2);
  833.     memcpy(&os2, pos2, min(OS_2_length, sizeof(os2)));
  834.     update_OS_2(&os2, 0xf000, 256);
  835.     pwrite(s, &os2, OS_2_length);
  836.     put_pad(s, OS_2_length);
  837.     } else {
  838.     /* Just copy the existing OS/2 table. */
  839.     write_range(s, pfont, OS_2_start, OS_2_length);
  840.     put_pad(s, OS_2_length);
  841.     }
  842.  
  843.     /* If necessary, write post. */
  844.  
  845.     if (!have_post) {
  846.     if (options & WRITE_TRUETYPE_POST)
  847.         write_post(s, font, &post);
  848.     else {
  849.         byte post_initial[32 + 2];
  850.  
  851.         memset(post_initial, 0, 32);
  852.         put_u32(post_initial, 0x00030000);
  853.         pwrite(s, post_initial, 32);
  854.     }
  855.     }
  856.  
  857.     /* Write head. */
  858.  
  859.     /****** CHECKSUM WAS NEVER COMPUTED ******/
  860.     /*
  861.      * The following nonsense is to avoid warnings about the constant
  862.      * 0xb1b0afbaL being "unsigned in ANSI C, signed with -traditional".
  863.      */
  864. #if ARCH_SIZEOF_LONG > ARCH_SIZEOF_INT
  865. #  define HEAD_MAGIC 0xb1b0afbaL
  866. #else
  867. #  define HEAD_MAGIC ((ulong)~0x4e4f5045)
  868. #endif
  869.     put_u32(head + 8, HEAD_MAGIC - file_checksum); /* per spec */
  870. #undef HEAD_MAGIC
  871.     pwrite(s, head, 56);
  872.  
  873.     return 0;
  874. }
  875.  
  876. /* Write a TrueType font. */
  877. int
  878. psf_write_truetype_font(stream *s, gs_font_type42 *pfont, int options,
  879.             gs_glyph *orig_subset_glyphs, uint orig_subset_size,
  880.             const gs_const_string *alt_font_name)
  881. {
  882.     gs_font *const font = (gs_font *)pfont;
  883.     psf_glyph_enum_t genum;
  884.     gs_glyph subset_data[256 * MAX_COMPOSITE_PIECES];
  885.     gs_glyph *subset_glyphs = orig_subset_glyphs;
  886.     uint subset_size = orig_subset_size;
  887.  
  888.     /* Sort the subset glyphs, if any. */
  889.  
  890.     if (subset_glyphs) {
  891.     /* Add the component glyphs for composites. */
  892.     int code;
  893.  
  894.     memcpy(subset_data, orig_subset_glyphs,
  895.            sizeof(gs_glyph) * subset_size);
  896.     subset_glyphs = subset_data;
  897.     code = psf_add_subset_pieces(subset_glyphs, &subset_size,
  898.                      countof(subset_data),
  899.                      countof(subset_data),
  900.                      font);
  901.     if (code < 0)
  902.         return code;
  903.     subset_size = psf_sort_glyphs(subset_glyphs, subset_size);
  904.     }
  905.     psf_enumerate_glyphs_begin(&genum, font, subset_glyphs,
  906.                    (subset_glyphs ? subset_size : 0),
  907.                    GLYPH_SPACE_INDEX);
  908.     return psf_write_truetype_data(s, pfont, options, &genum,
  909.                    subset_glyphs != 0, alt_font_name);
  910. }
  911.  
  912. /* Write a CIDFontType 2 font. */
  913. int
  914. psf_write_cid2_font(stream *s, gs_font_cid2 *pfont, int options,
  915.             const byte *subset_bits, uint subset_size,
  916.             const gs_const_string *alt_font_name)
  917. {
  918.     gs_font *const font = (gs_font *)pfont;
  919.     psf_glyph_enum_t genum;
  920.  
  921.     psf_enumerate_bits_begin(&genum, font, subset_bits,
  922.                  (subset_bits ? subset_size : 0),
  923.                  GLYPH_SPACE_INDEX);
  924.     return psf_write_truetype_data(s, (gs_font_type42 *)font, options, &genum,
  925.                    subset_bits != 0, alt_font_name);
  926. }
  927.